package org.anderground.app.storage.xml;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.anderground.app.storage.ConfigReader;
import org.anderground.app.storage.ConfigWriter;
import org.anderground.app.storage.CreatingStorageException;
import org.anderground.app.storage.OnProgressCallback;
import org.anderground.app.storage.PersistentStorage;
import org.anderground.app.storage.ConfigData.ConfigCity;
import org.anderground.core.storage.ModelReader;
import org.anderground.core.storage.ModelWriter;
import org.anderground.modules.storage.xml.XmlModelStorage;

/**
 * Adapter for the core {@link XmlModelStorage} class.
 * 
 * @author Eldar Abusalimov
 */
public abstract class XmlStorage extends PersistentStorage {

	/**
	 */
	public XmlStorage() {
	}

	@Override
	public final ModelReader getReaderForCity(ConfigCity city)
			throws CreatingStorageException {
		try {
			InputStream inputStream = openInputStreamForCity(city);
			if (inputStream == null) {
				throw new CreatingStorageException(
						"unable to open InputStream (null)");
			}
			return XmlModelStorage.createReader(inputStream, true);
		} catch (IOException e) {
			throw new CreatingStorageException("unable to open InputStream", e);
		}
	}

	@Override
	public final ModelWriter getWriterForCity(ConfigCity city)
			throws CreatingStorageException {
		try {
			OutputStream outputStream = openOutputStreamForCity(city);
			if (outputStream == null) {
				throw new CreatingStorageException(
						"unable to open OutputStream (null)");
			}
			return XmlModelStorage.createWriter(outputStream, true);
		} catch (IOException e) {
			throw new CreatingStorageException("unable to open OutputStream", e);
		}
	}

	@Override
	protected final ConfigReader getConfigReader(
			OnProgressCallback onProgressCallback)
			throws CreatingStorageException {
		try {
			InputStream inputStream = openConfigInputStream();
			if (inputStream == null) {
				throw new CreatingStorageException(
						"unable to open InputStream (null)");
			}
			return new SaxConfigReader(inputStream, true, onProgressCallback);
		} catch (IOException e) {
			throw new CreatingStorageException("unable to open InputStream", e);
		}
	}

	@Override
	protected final ConfigWriter getConfigWriter(
			OnProgressCallback onProgressCallback)
			throws CreatingStorageException {
		throw new CreatingStorageException("xml writing is not implemented");
	}

	protected abstract InputStream openInputStreamForCity(ConfigCity city)
			throws IOException;

	protected abstract OutputStream openOutputStreamForCity(ConfigCity city)
			throws IOException;

	protected abstract InputStream openConfigInputStream() throws IOException;

	protected abstract OutputStream openConfigOutputStream() throws IOException;

}
